use core::time;
use std::collections::HashMap;
use std::f32::consts::E;
use std::io::Read;

use serde::Deserialize;
use serde_json::{to_string, Value};
use std::path::Path;
use std::sync::Arc;
use std::time::Duration;
use tokio::sync::Mutex;
// 引入必要的库
use ssh2::{Channel, Session, Sftp};
use tauri::{window, App, Context, Manager, Runtime, Window};
use tokio::fs::File;
use tokio::sync::{mpsc, oneshot};
use tokio_tungstenite::tungstenite::Bytes;
use tokio_tungstenite::tungstenite::Message;
use tokio_tungstenite::tungstenite::Utf8Bytes;
use tokio_tungstenite::{tungstenite, WebSocketStream};
use window_shadows::set_shadow;
// Learn more about Tauri commands at https://tauri.app/v1/guides/features/command

//use std::net::SocketAddr;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
//use tokio::net::{TcpSocket, TcpStream};
use tokio;
use tokio::sync::broadcast::{self, Sender};
//use tokio_tungstenite::accept_async;
use crate::entity::structs::MyMessage;
use futures_util::{SinkExt, StreamExt};
use log::*;
use std::net::SocketAddr;
use tokio::fs::{self};
//use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::net::{TcpListener, TcpStream};
use tokio_tungstenite::{
    accept_async,
    tungstenite::{Error, Result},
};

lazy_static! {
    pub static ref HASHMAP: HashMap<String, &'static str> = {
        let mut m = HashMap::new();
        m.insert(format!("{}-{}", 0, 0), "foo");
        m
    };
}

// #[derive(Debug)]
pub struct SshSession {
    session: Session,
    channel: Channel,
}

pub struct SshManager {
    sessions: HashMap<String, SshSession>,
    current_session_id: Option<String>,
}

impl SshManager {
    pub fn new() -> Self {
        SshManager {
            sessions: HashMap::new(),
            current_session_id: None,
        }
    }

    fn add_session(&mut self, id: String, session: Session, channel: Channel) {
        self.sessions.insert(id, SshSession { session, channel });
    }

    fn switch_session(&mut self, id: &str) -> Result<(), String> {
        if self.sessions.contains_key(id) {
            self.current_session_id = Some(id.to_string());
            Ok(())
        } else {
            Err(format!("Session with ID {} not found", id))
        }
    }

    fn get_current_session(&self) -> Option<&SshSession> {
        self.current_session_id
            .as_ref()
            .and_then(|id| self.sessions.get(id))
    }

    fn get_current_session_mut(&mut self) -> Option<&mut SshSession> {
        self.current_session_id
            .as_ref()
            .and_then(|id| self.sessions.get_mut(id))
    }
}

pub async fn accept_connection(
    peer: SocketAddr,
    stream: TcpStream,
    tx: mpsc::Sender<String>,
    ssh_manager: Arc<Mutex<SshManager>>,
) {
    if let Err(e) = handle_connection(peer, stream, tx.clone(), ssh_manager).await {
        match e {
            Error::ConnectionClosed | Error::Protocol(_) | Error::Utf8 => {
                println!("connection match: ")
            }
            err => error!("Error processing connection: {}", err),
        }
    }
}
// fn get_result<T>(json: &str) -> Result<Message<T>, anyhow::Error> {
//     let r: Message<T> = serde_json::from_str(json).unwrap();
//     Ok(r)
// }
// fn get_result<T: for<'a> Deserialize<'a>>(json: &str) -> Message<T> {
//     let r: Message<T> = serde_json::from_str(json).unwrap();
//     Ok(r)
// }

// fn get_result<T: for<'a> Deserialize<'a>>(json: serde_json::Value) -> Result<Message<T>, anyhow::Error> {
//     let r: Message<T> = serde_json::from_value(json)?;
//     Ok(r)
// }
pub async fn handle_connection(
    peer: SocketAddr,
    stream: TcpStream,
    tx: mpsc::Sender<String>,
    ssh_manager: Arc<Mutex<SshManager>>,
) -> Result<()> {
    let mut ws_stream = accept_async(stream).await.expect("Failed to accept");
    println!("New WebSocket connection: {}", peer);

    let session_id = "session1".to_string(); // 假设会话ID为 "session1"

    let tcp = TcpStream::connect("124.71.113.66:22").await.unwrap();
    let mut session = Session::new().unwrap();
    session.set_tcp_stream(tcp);
    //ssh 连接
    while let Some(msg) = ws_stream.next().await {
        let msg = msg.unwrap();
        println!("地址: {}, msg: {}", peer, msg);
        if msg.is_text() || msg.is_binary() {
            if msg.is_text() {
                let message = msg.clone().into_text().unwrap();
                let mut v2: Result<MyMessage, serde_json::Error> = serde_json::from_str(&message);
                match v2 {
                    Ok(mut v) => {
                        //心跳
                        if (v.message_type == "HEARTBEAT") {
                            //心跳测试
                            //println!("心跳测试: {}", v.get_message());
                            let str_: String = serde_json::to_string(&v).unwrap();
                            let mut ok_ = Message::into_text(str_.into())?;
                            ws_stream.send(tungstenite::Message::Text(ok_));
                        } else {
                            let mut ok = session.handshake();
                            match ok {
                                Ok(_) => {
                                    //session.set_timeout(120000);
                                    if !session.authenticated() {
                                        session.userauth_password("root", "1314520jC").unwrap();
                                    }
                                    //session.userauth_password("root", "1314520jC").unwrap();
                                    let authenticated = session.authenticated();
                                    println!("authenticated: {}", authenticated);
                                    if authenticated {
                                        let channel = session.channel_session().unwrap();
                                        let mut manager = ssh_manager.lock().await;
                                        manager.add_session(
                                            session_id.clone(),
                                            session.clone(),
                                            channel,
                                        );
                                        manager.switch_session(&session_id).unwrap();

                                        // 启动心跳任务
                                        let ssh_manager_clone = ssh_manager.clone();
                                        tokio::spawn(async move {
                                            loop {
                                                tokio::time::sleep(Duration::from_secs(60)).await; // 每分钟发送一次心跳
                                                let mut manager = ssh_manager_clone.lock().await;
                                                if let Some(ssh_session) =
                                                    manager.get_current_session_mut()
                                                {
                                                    //命令
                                                    let mut s: String = String::new();
                                                    //获取Session连接通道
                                                    ssh_session.channel.exec("echo").unwrap();
                                                    let echo =
                                                        ssh_session.channel.read_to_string(&mut s);
                                                    if let Err(e) = echo {
                                                        error!("Heartbeat failed: {}", e);
                                                        // 处理心跳失败的情况，例如重新连接
                                                    }
                                                    // if let Err(e) = session
                                                    //     .channel
                                                    //     .exec("echo")
                                                    //     .unwrap()
                                                    //     .read_to_string(&mut String::new())
                                                    // {
                                                    //     error!("Heartbeat failed: {}", e);
                                                    //     // 处理心跳失败的情况，例如重新连接
                                                    // }
                                                }
                                            }
                                        });
                                        //let mut dir = sftp.opendir("/home").unwrap();
                                        if (v.message_type == "DOWNLOAD") {
                                            let remote_path = v.get_data(); // 假设data字段包含要下载的远程文件路径

                                            //let remote_path = "/path/to/remote_file";
                                            let local_path = "/tmp/remote_file.tmp";

                                            // 创建 SFTP 会话
                                            let sftp = session.sftp();
                                            match sftp {
                                                Ok(sftp_) => {
                                                    // 打开远程文件
                                                    let mut remote_file =
                                                        sftp_.open(Path::new(remote_path));

                                                    // 获取远程文件信息
                                                    let file_attrs =
                                                        sftp_.stat(Path::new(remote_path));
                                                    //创建本地文件
                                                    let mut local_file =
                                                        File::create(local_path).await?;
                                                    let mut buffer = vec![0; 4096]; // 可以根据实际情况调整缓冲区大小
                                                    match remote_file {
                                                        Ok(mut remote_file_) => {
                                                            loop {
                                                                match remote_file_.read(&mut buffer)
                                                                {
                                                                    Ok(0) => break, // 已经读取完毕
                                                                    n => {
                                                                        local_file
                                                                            .write_all(
                                                                                &buffer
                                                                                    [..n.unwrap()],
                                                                            )
                                                                            .await?;
                                                                        // 清空缓冲区以便下一次读取
                                                                        buffer.resize(4096, 0);
                                                                    }
                                                                }
                                                                // match remote_file_.read(&mut buffer) {
                                                                //     0 => break, // 已经读取完毕
                                                                //     n => {
                                                                //         local_file.write_all(&buffer[..n])?;
                                                                //         // 清空缓冲区以便下一次读取
                                                                //         buffer.resize(4096, 0);
                                                                //     }
                                                                // }
                                                            }
                                                            //确保文件内容已完全写入
                                                            local_file.flush().await.unwrap();

                                                            // 将临时文件通过WebSocket发送给前端
                                                            let mut file_content =
                                                                fs::read(local_path).await?;
                                                            ws_stream
                                                                .send(tungstenite::Message::Binary(
                                                                    Bytes::from(file_content),
                                                                ))
                                                                .await?;

                                                            // 清理临时文件（可选）
                                                            fs::remove_file(local_path).await.ok();
                                                        }
                                                        Err(e) => {
                                                            println!(
                                                                "Error opening remote file: {}",
                                                                e
                                                            );
                                                        }
                                                    }
                                                }
                                                Err(err) => {
                                                    v.set_data("获取sftp失败".to_string());
                                                    let str_: String =
                                                        serde_json::to_string(&v).unwrap();
                                                    let mut msg: Utf8Bytes =
                                                        Message::into_text(str_.into())?;
                                                    ws_stream
                                                        .send(tungstenite::Message::Text(msg))
                                                        .await?;
                                                }
                                            }
                                        } else {
                                            //获取Session连接通道
                                            let mut channel = session.channel_session().unwrap();
                                            //命令
                                            v.set_data(
                                                "收到前端的命令：".to_string() + v.get_data(),
                                            );
                                            //执行命令
                                            channel.exec(v.get_data()).unwrap();
                                            //获取ssh 返回信息
                                            let mut s: String = String::new();
                                            channel.read_to_string(&mut s).unwrap();
                                            v.set_data(s);
                                            let str_: String = serde_json::to_string(&v).unwrap();
                                            let mut msg: Utf8Bytes =
                                                Message::into_text(str_.into())?;
                                            ws_stream.send(tungstenite::Message::Text(msg)).await?;
                                            // ws_stream
                                            //     .send(tungstenite::Message::Text(
                                            //         serde_json::to_string(&v).unwrap(),
                                            //     ))
                                            //     .await?;
                                            channel.close();
                                        }
                                    } else {
                                        let mut v: MyMessage = MyMessage {
                                            message_type: "连接SSH服务器异常".to_string(),
                                            data: "认证失败".to_string(),
                                        };

                                        let str_: String = serde_json::to_string(&v).unwrap();
                                        let mut msg: Utf8Bytes = Message::into_text(str_.into())?;
                                        ws_stream.send(tungstenite::Message::Text(msg)).await?;
                                        // ws_stream
                                        //     .send(tungstenite::Message::Text(
                                        //         serde_json::to_string(&v).unwrap(),
                                        //     ))
                                        //     .await?;
                                    }
                                }
                                Err(e) => {
                                    println!("e.code()! {}", e.code());
                                    println!("e.message()! {}", e.message());
                                    println!("e.to_string()! {}", e.to_string());
                                    let mut v: MyMessage = MyMessage {
                                        message_type: "连接SSH服务器异常".to_string(),
                                        data: e.message().to_string(),
                                    };

                                    let str_: String = serde_json::to_string(&v).unwrap();
                                    let mut msg: Utf8Bytes = Message::into_text(str_.into())?;
                                    ws_stream.send(tungstenite::Message::Text(msg)).await?;
                                    println!("MyMessage {}", serde_json::to_string(&v).unwrap());
                                }
                            }
                        }
                    }
                    Err(e) => {
                        println!("Some msg: {}", e);
                    }
                }
            } else if (msg.is_binary()) {
                println!("msg is binary  msg: {}", msg);
            } else {
                println!("msg is other  msg: {}", msg);
            }
        } else {
            println!("msg非 text() || binary connection msg: {}", msg);
        }
    }
    Ok(())
}
